home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / berm122 / route.c < prev    next >
C/C++ Source or Header  |  1993-08-16  |  22KB  |  947 lines

  1. /**************************************************************************
  2.  *  ROUTE.C                                                               *
  3.  *                                                                        *
  4.  *  Proces route information for BERMUDA-P.                               *
  5.  *                                                                        *
  6.  * Written by Jac Kersing                                                 *
  7.  **************************************************************************/
  8.  
  9. #define MAILER              /* needed in PANDORA.H */
  10. #include "pandora.h"        /* for structure of the area's etc. */
  11.  
  12. /*#pragma warn -rng*/
  13.  
  14. #if TC
  15. #include <dos.h>
  16. #endif
  17.  
  18. #include "patmat.pro"
  19. #include "route.pro"
  20. #include "utextra.pro"
  21.  
  22. #define DEBUG    0          /* show debugging info? */
  23.  
  24. #if MEGAMAX || MWC
  25. char    *malloc(), *realloc();
  26. #endif
  27.  
  28. #define STRING      0
  29. #define ARCMAIL     1
  30. #define ROUTE_TO    2
  31. #define NO_ROUTE    3
  32. #define FORWARD_FOR 4
  33. #define TO          5
  34. #define NODE        6
  35. #define IF          7
  36. #define REDIRECT    8
  37. #define HOLD        9
  38. #define POLL        10
  39. #ifdef LINN
  40. #define NOHOLD      11
  41. #define ZIPMAIL     20
  42. #define LZHMAIL     21
  43. #define ZOOMAIL     22
  44. #define ARJMAIL     23
  45. #endif
  46. #define FIRST       0x1000
  47. #define CRASHMAIL   0x2000
  48. #define REQUEST     0x4000
  49. #define KW_FILE     0x8000
  50. #define MASK        0x00ff
  51.  
  52. struct _route
  53. {
  54.   char node[21];        /* spec for a node */
  55.   int  maxkbfile;       /* maximum number of bytes for files */
  56.   int  flags;
  57. } ;
  58.  
  59. extern char *skip_blanks();
  60. extern char *skip_to_blank();
  61. extern char *Bpath;
  62. extern struct _aka
  63.        {
  64.         int zone;
  65.         int net;
  66.         int node;
  67.         int point;
  68.         int pointnet;
  69.        } alias[];
  70. extern int nalias;
  71. extern char active[];
  72.  
  73. FILE *routef;
  74. #ifdef LINN
  75. #define ARC 0
  76. #define ZIP 1
  77. #define ZOO 2
  78. #define LZH 3
  79. #define ARJ 4
  80. struct _arc {
  81.     char *address;    /* node address */
  82.     int  archiveur; /* number of archiver */
  83. } *arc;
  84. #else
  85. char **arc;                     /* pointer to strings with arcmail specs */
  86. #endif
  87. int  maxanode;
  88. int  anode;
  89. struct _route *route;           /* routing info stored here */
  90. int  maxrnode;
  91. int  rnode;
  92. char buffer[255];               /* for parsing of routefile */
  93. char yytext[255];
  94. int token;
  95. int store;
  96. char pattern[10][40];           /* for pattern matcher */
  97.  
  98.  
  99. /* The program.... */
  100.  
  101. int isok(string)
  102. char *string;
  103. {
  104.     char *p;
  105.     char foundcolon=0, foundslash=0;
  106.  
  107.     for (p= string; *p; p++)
  108.     {
  109.         if (*p==':')
  110.         {
  111.             if (foundcolon) return -1;
  112.             else foundcolon++;
  113.         }
  114.         else if (*p=='/')
  115.         {
  116.             if (foundslash) return -1;
  117.             else foundslash++;
  118.         }
  119.         else if (*p=='.' && p==string) continue;
  120.         else if (isspace(*p)) break;
  121.         else if (*p=='$' && isdigit(*(p+1))) { p++; continue; }
  122.         else if (*p!='*' && *p!='?' && !isdigit(*p)) return -1;
  123.     }
  124.     return (int) (p-string);
  125. }
  126.  
  127. int yyparse()
  128. {
  129.     int i;
  130.     char *p;
  131.     int ch;
  132.  
  133.     p= buffer;
  134.     while ((ch=getc(routef))!=EOF && (!isspace(ch) || p==buffer))
  135.     {
  136.         if (!isspace(ch))
  137.         {
  138.             if (ch==';')        /* skip comment */
  139.             {
  140.                 while( (ch=getc(routef))!=EOF && ch!='\n' && ch!='\r') ;
  141.                 continue;       /* OUTER LOOP !! */
  142.             }
  143.             *p++=ch;
  144.             if (p-buffer > 240)
  145.             {
  146.                 message(6,"!String > 240 chars in routefile");
  147.                 exit(2);
  148.             }
  149.         }
  150.     }
  151.     if (ch==EOF && p==buffer) return EOF;
  152.  
  153.     *p='\0';
  154.     p= buffer;
  155. #if DEBUG
  156. message(6," command: %s",p);
  157. #endif
  158.     if (!stricmp(p,"forward-from"))
  159.     {
  160.         return FORWARD_FOR;
  161.     }
  162.  
  163.     if (!stricmp(p,"to"))
  164.     {
  165.         return TO;
  166.     }
  167.  
  168.     if (!stricmp(p,"route-to"))
  169.     {
  170.         return ROUTE_TO;
  171.     }
  172.     
  173.     if (!stricmp(p,"no-route"))
  174.     {
  175.         return NO_ROUTE;
  176.     }
  177.  
  178.     if (!stricmp(p,"ARCMAIL"))
  179.     {
  180.         return ARCMAIL;
  181.     }
  182.  
  183. #ifdef LINN
  184.     if (!stricmp(p,"ZIPMAIL"))
  185.     {
  186.         return ZIPMAIL;
  187.     }
  188.     
  189.     if (!stricmp(p,"LZHMAIL"))
  190.     {
  191.         return LZHMAIL;
  192.     }
  193.     
  194.     if (!stricmp(p,"ZOOMAIL"))
  195.     {
  196.         return ZOOMAIL;
  197.     }
  198.     
  199.     if (!stricmp(p,"ARJMAIL"))
  200.     {
  201.         return ARJMAIL;
  202.     }
  203. #endif
  204.  
  205.     if (!stricmp(p,"HOLD"))
  206.     {
  207.         return HOLD;
  208.     }
  209.     
  210. #ifdef LINN
  211.     if(!stricmp(p,"NO-HOLD"))
  212.     {
  213.         return NOHOLD;
  214.     }
  215. #endif
  216.  
  217.     if (!stricmp(p,"POLL"))
  218.     {
  219.         return POLL;
  220.     }
  221.  
  222.     if (!stricmp(p,"CRASH"))
  223.     {
  224.         return CRASHMAIL;
  225.     }
  226.  
  227.     if (!stricmp(p,"FILE"))
  228.     {
  229.         return KW_FILE;
  230.     }
  231. /*
  232.     if (!stricmp(p,"REQUEST"))
  233.     {
  234.         return REQUEST;
  235.     }
  236. */
  237.     if (!stricmp(p,"IF"))
  238.     {
  239.         return IF;
  240.     }
  241.  
  242.     if (!stricmp(p,"REDIRECT"))
  243.     {
  244.         return REDIRECT;
  245.     }
  246.  
  247.     if (!stricmp(p,"ALL"))
  248.     {
  249.         strcpy(yytext,"*");
  250.         return NODE;
  251.     }
  252.  
  253.     if (!stricmp(p,"ournet"))
  254.     {
  255.         sprint(yytext,"%d:%d/*",alias[0].zone,alias[0].net);
  256.         return NODE;
  257.     }
  258.  
  259.     if (!stricmp(p,"boss"))
  260.     {
  261.         sprint(yytext,"%d:%d/%d",alias[0].zone,alias[0].net,alias[0].node);
  262.         return NODE;
  263.     }
  264.  
  265.     if (!stricmp(p,"points"))
  266.     {
  267.         strcpy(yytext,".*");
  268.         return NODE;
  269.     }
  270.  
  271.     i= isok(p);
  272.     if (i>0)
  273.     {
  274.         strncpy(yytext,p,i);
  275.         yytext[i]= '\0';
  276.  
  277.         if (strchr("?*$",*yytext) != NULL) return (NODE);
  278.         if (strchr(yytext,'.') != NULL) return NODE;
  279.         if (strchr(yytext,':') != NULL) return NODE;
  280.         if (strchr(yytext,'/') == NULL)
  281.         {
  282.             char buf[80];
  283.             sprint(buf,"%d:%d/%s",alias[0].zone, alias[0].net, yytext);
  284.             strcpy(yytext,buf);
  285.         }
  286.         else
  287.         {
  288.             char buf[80];
  289.             sprint(buf,"%d:%s", alias[0].zone, yytext);
  290.             strcpy(yytext,buf);
  291.         }
  292.         return NODE;
  293.     }
  294.  
  295.     strcpy(yytext,buffer);
  296.     return STRING;
  297. }
  298.  
  299. void parse()
  300. {
  301.         token= yyparse();
  302. }
  303.  
  304. #ifdef LINN
  305. void arcmail(int archiveur)
  306. {
  307.         /* Found ARCMAIL in the input, read nodenumbers next */
  308.         do
  309.         {
  310.                 parse();
  311.                 if (token==NODE && store)
  312.                 {
  313.                         arc[anode].address= malloc(strlen(yytext)+1);
  314.                         if (arc[anode].address==NULL)
  315.                         {
  316.                                 message(6,"!Mem error");
  317.                                 exit(1);
  318.                         }
  319.                         strcpy(arc[anode].address,yytext);
  320.                         arc[anode].archiveur=archiveur;
  321.                         anode++;
  322.                         if (anode>=maxanode)
  323.                         {
  324.                                 maxanode += 1000;
  325.                                 arc= realloc(arc, maxanode * sizeof(struct _arc));
  326.                                 if (arc==NULL)
  327.                                 {
  328.                                         message(6,"!Mem error");
  329.                                         exit(1);
  330.                                 }
  331.                         }
  332.                 }
  333.         }
  334.         while (token==NODE) ;
  335. }
  336. #else
  337. void arcmail()
  338. {
  339.         /* Found ARCMAIL in the input, read nodenumbers next */
  340.         do
  341.         {
  342.                 parse();
  343.                 if (token==NODE && store)
  344.                 {
  345.                         arc[anode]= malloc(strlen(yytext)+1);
  346.                         if (arc[anode]==NULL)
  347.                         {
  348.                                 message(6,"!Mem error");
  349.                                 exit(1);
  350.                         }
  351.                         strcpy(arc[anode],yytext);
  352.                         anode++;
  353.                         if (anode>=maxanode)
  354.                         {
  355.                                 maxanode += 1000;
  356.                                 arc= realloc(arc, maxanode * sizeof(struct _arc));
  357.                                 if (arc==NULL)
  358.                                 {
  359.                                         message(6,"!Mem error");
  360.                                         exit(1);
  361.                                 }
  362.                         }
  363.                 }
  364.         }
  365.         while (token==NODE) ;
  366. }
  367. #endif
  368.  
  369. void addroute(flags)
  370. int flags;
  371. {
  372.         if (!store) return;
  373.  
  374.         strncpy(route[rnode].node,yytext,20);
  375.         route[rnode].node[20]='\0';
  376.         route[rnode].flags= flags;
  377.         route[rnode].maxkbfile= 0;
  378.         rnode++;
  379.         if (rnode >= maxrnode)
  380.         {
  381.                 maxrnode += 1000;
  382.                 route=realloc(route, sizeof(struct _route) * maxrnode);
  383.                 if (route==NULL)
  384.                 {
  385.                         message(6,"!Mem error");
  386.                         exit(1);
  387.                 }
  388.         }
  389. }
  390.  
  391. void route_to()
  392. {
  393.         int flags= ROUTE_TO|FIRST;
  394.  
  395.         do
  396.         {
  397.                 parse();
  398.                 if (token==CRASHMAIL) flags |= CRASHMAIL;
  399.                 if (token==KW_FILE) flags |= KW_FILE;
  400.                 if (token==NODE)
  401.                 {
  402.                         addroute(flags);
  403.                         flags &= ~FIRST;
  404.                 }
  405.         }
  406.         while (token==NODE || token==CRASHMAIL || token==KW_FILE);
  407. }
  408.  
  409. void no_route()
  410. {
  411.         int flags= NO_ROUTE;
  412.  
  413.         do
  414.         {
  415.                 parse();
  416.                 if (token==CRASHMAIL) flags |= CRASHMAIL;
  417.                 if (token==KW_FILE) flags |= KW_FILE;
  418.                 if (token==NODE)
  419.                 {
  420.                         addroute(flags);
  421.                 }
  422.         }
  423.         while (token==NODE || token==CRASHMAIL || token==KW_FILE);
  424. }
  425.  
  426. void add_hold()
  427. {
  428.         int flags= HOLD;
  429.  
  430.         do
  431.         {
  432.                 parse();
  433.                 if (token==NODE)
  434.                 {
  435.                         addroute(flags);
  436.                 }
  437.         }
  438.         while (token==NODE);
  439. }
  440.  
  441. void add_poll()
  442. {
  443.         int flags= POLL;
  444.  
  445.         do
  446.         {
  447.                 parse();
  448.                 if (token==NODE)
  449.                 {
  450.                         addroute(flags);
  451.                 }
  452.         }
  453.         while (token==NODE);
  454. }
  455.  
  456. #ifdef LINN /* ho-hold */
  457. void add_nohold()
  458. {
  459.         int flags= NOHOLD;
  460.  
  461.         do
  462.         {
  463.                 parse();
  464.                 if (token==NODE)
  465.                 {
  466.                         addroute(flags);
  467.                 }
  468.         }
  469.         while (token==NODE);
  470. }
  471. #endif
  472.  
  473. void forward()
  474. {
  475.         int flags= FORWARD_FOR;
  476.  
  477.         do
  478.         {
  479.                 parse();
  480.                 if (token==CRASHMAIL) flags |= CRASHMAIL;
  481.                 if (token==KW_FILE) flags |= KW_FILE;
  482.                 if (token==TO) flags= TO | (flags & ~MASK);
  483.                 if (token==NODE)
  484.                 {
  485.                         addroute(flags);
  486.                 }
  487.         }
  488.         while (token==NODE || token==CRASHMAIL || token==TO || token==KW_FILE);
  489. }
  490.  
  491. void if_ok()
  492. {
  493.         /* Found IF in the input, check for tag next */
  494.         parse();
  495.  
  496.         if (token!=STRING)
  497.         {
  498.             message(6,"!Invalid TAG");
  499.             return;
  500.         }
  501.  
  502.         store= !stricmp(yytext,active);
  503.         parse();
  504. }
  505.  
  506. void redirect()
  507. {
  508.         /* found redirect in input, now store nodes */
  509.         int flags= REDIRECT|FIRST;
  510.  
  511.         do
  512.         {
  513.                 parse();
  514.                 if (token==CRASHMAIL) flags |= CRASHMAIL;
  515.                 if (token==NODE)
  516.                 {
  517.                         addroute(flags);
  518.                         flags &= ~FIRST;
  519.                 }
  520.         }
  521.         while (token==NODE || token==CRASHMAIL);
  522. }
  523.  
  524. int parse_route()
  525. {
  526.     sprintf( buffer, "%sbermuda.rte", Bpath);
  527.     routef= fopen(buffer,"r");
  528.     
  529.     if (routef == NULL)
  530.     {
  531.         sprintf( buffer, "%stb.rte", Bpath);
  532.         routef = fopen(buffer,"r");
  533.     }
  534.  
  535.     if (routef==NULL)
  536.     {
  537.         message(6,"!Can not find ROUTE file, please check!!");
  538.         exit(2);
  539.     }
  540.     
  541.     arc=malloc(1000 * sizeof(struct _arc));
  542.     maxanode=1000;
  543.     anode=0;
  544.  
  545.     if (arc==NULL)
  546.        {
  547.            message(6,"!Mem error");
  548.            exit(1);
  549.        }
  550.  
  551.     route=malloc(1000 * sizeof(struct _route));
  552.     maxrnode= 1000;
  553.     rnode= 0;
  554.  
  555.     store= 1;
  556.  
  557.     parse();
  558.     while (token != EOF)
  559.     {
  560.         switch(token)
  561.         {
  562. #ifdef LINN
  563.          case NOHOLD  : add_nohold(); break;
  564.          case ARCMAIL : arcmail(ARC);  break;
  565.          case ZIPMAIL : arcmail(ZIP);  break;
  566.          case LZHMAIL : arcmail(LZH);  break;
  567.          case ARJMAIL : arcmail(ARJ);  break;
  568.          case ZOOMAIL : arcmail(ZOO);  break;
  569. #else
  570.          case ARCMAIL : arcmail();  break;
  571. #endif
  572.          case ROUTE_TO: route_to(); break;
  573.          case NO_ROUTE: no_route(); break;
  574.          case FORWARD_FOR: forward(); break;
  575.          case IF      : if_ok();    break;
  576.          case REDIRECT: redirect(); break;
  577.          case HOLD    : add_hold(); break;
  578.          case POLL    : add_poll(); break;
  579.          default      : printf("Error in %s\n",buffer);
  580.                         parse();
  581.         }
  582.     }
  583.     
  584.     fclose(routef);
  585.     return 0;
  586. }
  587.  
  588. #ifdef LINN
  589. int ArcOk(zone,net,node)
  590. int zone, net, node;
  591. {
  592.         char buffer[80];
  593.         int i, ret;
  594.  
  595.         sprint(buffer,"%d:%d/%d",zone,net,node);
  596.         for(i=0; i<nalias; i++)
  597.         {
  598.             if (alias[i].point==0)
  599.             {
  600.                 if (alias[i].zone==zone && alias[i].pointnet==net)
  601.                 {
  602.                     sprint(buffer,".%d",node);
  603.                 }
  604.             }
  605.         }
  606.  
  607.         ret=-1;
  608.         for (i=0; i<anode; i++)
  609.         {
  610.                 if (patmat(buffer,arc[i].address))
  611.             ret=arc[i].archiveur;
  612.         }
  613.         return ret;
  614. }
  615. #else
  616. int ArcOk(zone,net,node)
  617. int zone, net, node;
  618. {
  619.         char buffer[80];
  620.         int i;
  621.  
  622.         sprint(buffer,"%d:%d/%d",zone,net,node);
  623.         for(i=0; i<nalias; i++)
  624.         {
  625.             if (alias[i].point==0)
  626.             {
  627.                 if (alias[i].zone==zone && alias[i].pointnet==net)
  628.                 {
  629.                     sprint(buffer,".%d",node);
  630.                 }
  631.             }
  632.         }
  633.  
  634.         for (i=0; i<anode; i++)
  635.         {
  636.                 if (patmat(buffer,arc[i])) return 1;
  637.         }
  638.         return 0;
  639. }
  640. #endif
  641.  
  642. int HoldOk(zone,net,node)
  643. int zone, net, node;
  644. {
  645.         char buffer[80];
  646.         int i;
  647. #ifdef LINN
  648.         int dohold=0;
  649. #endif
  650.         sprint(buffer,"%d:%d/%d",zone,net,node);
  651.         for(i=0; i<nalias; i++)
  652.         {
  653.             if (alias[i].point==0)
  654.             {
  655.                 if (alias[i].zone==zone && alias[i].pointnet==net)
  656.                 {
  657.                     sprint(buffer,".%d",node);
  658.                 }
  659.             }
  660.         }
  661.  
  662.         for (i=0; i<rnode; i++)
  663.         {
  664.                 if (((route[i].flags&MASK)==HOLD) &&
  665.                     patmat(buffer,route[i].node)) 
  666. #ifdef LINN
  667.                     dohold=1;
  668. #else
  669.                     return 1;
  670. #endif
  671.         }
  672.  
  673. #ifdef LINN
  674.         for (i=0; i<rnode; i++)
  675.         {
  676.                 if (((route[i].flags&MASK)==NOHOLD) &&
  677.                     patmat(buffer,route[i].node)) dohold=0;
  678.         }
  679.         return dohold;
  680. #else
  681.         return 0;
  682. #endif
  683. }
  684.  
  685. int ForwardOk(fromzone,fromnet,fromnode,frompoint,
  686.               tozone,tonet,tonode,topoint,
  687.               crash,file)
  688. int fromzone, fromnet, fromnode, frompoint;
  689. int tozone, tonet, tonode, topoint;
  690. int crash,file;
  691. {
  692.         int i;
  693.         char buffer1[80];
  694.         char buffer2[80];
  695.  
  696.         /* Should do checking for points (our points!) also */
  697.  
  698.         sprint(buffer1,"%d:%d/%d",fromzone,fromnet,fromnode);
  699.         if (frompoint)
  700.         {
  701.             for(i=0; i<nalias; i++)
  702.             {
  703.                 if (alias[i].point==0 && alias[i].zone==fromzone &&
  704.                     alias[i].net==fromnet && alias[i].node==fromnode)
  705.                 {
  706.                     sprint(buffer1,".%d",frompoint);
  707.                 }
  708.             }
  709.         }
  710.  
  711.         sprint(buffer2,"%d:%d/%d",tozone,tonet,tonode);
  712.         if (topoint)
  713.         {
  714.             for(i=0; i<nalias; i++)
  715.             {
  716.                 if (alias[i].point==0 && alias[i].zone==tozone &&
  717.                     alias[i].net==tonet && alias[i].node==tonode)
  718.                 {
  719.                     sprint(buffer1,".%d",topoint);
  720.                 }
  721.             }
  722.         }
  723.  
  724.         for (i=0; i<rnode; i++)
  725.         {
  726.             if ((route[i].flags&MASK)== FORWARD_FOR)
  727.             {
  728.                 if (patmat(buffer1,route[i].node))
  729.                 {
  730.                     /* for part matches, now skip rest of for part */
  731.                     for(;i<rnode && (route[i].flags&MASK)==FORWARD_FOR; i++) ;
  732.  
  733.                     /* AS long we are in the to part check destination */
  734.                     for(;i<rnode && (route[i].flags&MASK)==TO; i++)
  735.                     {
  736.                         if (patmat(buffer2,route[i].node))
  737.                         {
  738.                            /* File attached? Do we fwd files? No -> next */
  739.                            if (file && !(route[i].flags&KW_FILE)) continue;
  740.                            
  741.                            /* crash && forward crash? No -> next */
  742.                            if (crash && (route[i].flags&CRASHMAIL)) return 1;
  743.                            if (!crash && !(route[i].flags&CRASHMAIL)) return 1;
  744.                         }
  745.                     }
  746.                 }
  747.             }
  748.         }
  749.         return 0;
  750. }
  751.  
  752. int match(raw,pat)
  753. char *raw, *pat;
  754. {
  755.         int i;
  756.  
  757.         for (i=0; i<10; i++)
  758.         {
  759.                 pattern[i][0]='\0';
  760.         }
  761.         return match1(raw,pat,1);
  762. }
  763.  
  764. int match1(raw, pat, level)
  765. char *raw;
  766. char *pat;
  767. int level;
  768. {  int  i ;
  769.  
  770.    if ((*pat == '\0') && (*raw == '\0'))    /*  if it is end of both  */
  771.      return( 1 ) ;                          /*  strings,then match    */
  772.    if (*pat == '\0')                        /*  if it is end of only  */
  773.      return( 0 ) ;                          /*  pat then mismatch     */
  774.    if (*pat == '*')                         /* if pattern is a '*'    */
  775.    {
  776.         if (*(pat+1) == '\0')               /*    if it is end of pat */
  777.          return( 1 ) ;                      /*    then match          */
  778.         for(i=0;i<=(int)strlen(raw);i++)           /*    else hunt for match */
  779.          if ((*(raw+i) == *(pat+1)) ||       /*         or wild card   */
  780.             (*(pat+1) == '?'))
  781.          {
  782.            strcpy(pattern[level],raw);
  783.            pattern[level][i]='\0';
  784.            if (match1(raw+i+1,pat+2,level+1) == 1) return( 1 ) ;
  785.          }
  786.     }
  787.    else
  788.     { if (*raw == '\0')                     /*  if end of raw then    */
  789.          return( 0 ) ;                      /*     mismatch           */
  790.       if ((*pat == *raw))
  791.         if (match1(raw+1,pat+1,level) == 1)       /*  try & match rest of it*/
  792.            return( 1 ) ;
  793.       if (*pat == '?')
  794.       {
  795.         pattern[level][0]= *raw;
  796.         pattern[level][1]= '\0';
  797.         if (match1(raw+1,pat+1,level+1) == 1) return( 1 ) ;
  798.       }
  799.     }
  800.    return( 0 ) ;                            /*  no match found        */
  801. }
  802.  
  803. void getid(nr,zone,net,node)
  804. int nr, *zone, *net, *node;
  805. {
  806.     char buffer[80];
  807.     char *p= route[nr].node;
  808.     int i,b;
  809.  
  810.     if (strchr(p,'.')!=NULL)
  811.     {
  812.         sprint(buffer,"%d:%d/%d",alias[0].zone, alias[0].net, alias[0].node);
  813.     }
  814.     else
  815.     {
  816.         for(b=i=0;i<(int)strlen(p);i++)
  817.         {
  818.             if (p[i]=='$')
  819.             {
  820.                 i++;
  821.                 strcpy(&buffer[b],pattern[p[i]-'0']);
  822.                 while (buffer[b]) b++;
  823.             }
  824.             else buffer[b++]=p[i];
  825.         }
  826.     }
  827. #ifdef LINN
  828.     /* the mysterious bug was here */
  829.     buffer[b]='\0';
  830. #endif
  831.  
  832.     /* Now the buffer contains an explicit node */
  833.     *zone= alias[0].zone;
  834.     *net= alias[0].net;
  835.     *node= alias[0].node;
  836.     sscanf(buffer,"%d:%d/%d",zone,net,node);
  837. }
  838.  
  839. void ToWhere(zone, net, node, dzone, dnet, dnode, dpoint, crash, file)
  840. int *zone, *net, *node, dzone, dnet, dnode, dpoint, crash, file;
  841. {
  842.     int i;
  843.     int first;
  844.     char buffer1[80];
  845.     int chk = (crash ? CRASHMAIL : 0) | (file ? KW_FILE : 0);
  846.  
  847.     *zone= dzone;
  848.     *net= dnet;
  849.     *node= dnode;
  850.  
  851.     /* Do something for points here too */
  852.     sprint(buffer1,"%d:%d/%d", dzone, dnet, dnode);
  853.     if (dpoint)
  854.     {
  855.         for(i=0; i<nalias; i++)
  856.         {
  857.             if (alias[i].point==0 && alias[i].zone==dzone &&
  858.                 alias[i].net==dnet && alias[i].node==dnode)
  859.             {
  860.                 sprint(buffer1,".%d",dpoint);
  861.                 *net = dnet = alias[i].pointnet;
  862.                 *node= dnode = dpoint;
  863.                 break;
  864.             }
  865.         }
  866.     }
  867.  
  868.     for (i=0; i<rnode; i++)
  869.     {
  870.         if ((route[i].flags&MASK)==ROUTE_TO)
  871.         {
  872.             for (;i<rnode && (route[i].flags&MASK)==ROUTE_TO; i++)
  873.             {
  874.                 if (route[i].flags&FIRST) first=i;
  875.                 if (chk != (route[i].flags&(CRASHMAIL|KW_FILE))) continue;
  876.                 if (match(buffer1,route[i].node)) getid(first,zone,net,node);
  877.             }
  878.         }
  879.         if ((route[i].flags&MASK)==NO_ROUTE)
  880.         {
  881.             if (patmat(buffer1,route[i].node))
  882.             {
  883.                 if (chk != (route[i].flags&(CRASHMAIL|KW_FILE))) continue;
  884.                 *zone= dzone;
  885.                 *net= dnet;
  886.                 *node= dnode;
  887.             }
  888.         }
  889.     }
  890. }
  891.  
  892. void ReDirectTo(zone, net, node, dzone, dnet, dnode, crash)
  893. int *zone, *net, *node, dzone, dnet, dnode, crash;
  894. {
  895.     int i;
  896.     int first;
  897.     char buffer1[80];
  898.     int chk = crash ? CRASHMAIL : 0;
  899.  
  900.     /* Do something for points here too */
  901.     sprint(buffer1,"%d:%d/%d", dzone, dnet, dnode);
  902.     for(i=0; i<nalias; i++)
  903.     {
  904.         if (alias[i].point==0)
  905.         {
  906.             if (alias[i].zone==dzone && alias[i].pointnet==dnet)
  907.             {
  908.                 sprint(buffer1,".%d",dnode);
  909.             }
  910.         }
  911.     }
  912.  
  913.     *zone= dzone;
  914.     *net= dnet;
  915.     *node= dnode;
  916.  
  917.     for (i=0; i<rnode; i++)
  918.     {
  919.         if ((route[i].flags&MASK)==REDIRECT)
  920.         {
  921.             for (;i<rnode && (route[i].flags&MASK)==REDIRECT; i++)
  922.             {
  923.                 if (route[i].flags&FIRST) first=i;
  924.                 if (chk != (route[i].flags&CRASHMAIL)) continue;
  925.                 if (match(buffer1,route[i].node)) getid(first,zone,net,node);
  926.             }
  927.         }
  928.     }
  929. }
  930.  
  931. char *PollNode(start)
  932. int *start;
  933. {
  934.         int i;
  935.  
  936.         for (i=(*start)+1; i<rnode; i++)
  937.         {
  938.                 if (route[i].flags==POLL)
  939.                 {
  940.                         *start= i;
  941.                         return route[i].node;
  942.                 }
  943.         }
  944.         return NULL;
  945. }
  946.  
  947.